package gxprod.androidai.functions;

import gxprod.androidai.AIActivity;
import gxprod.androidai.AnswerReciever;
import gxprod.androidai.BubbleAdapter;
import gxprod.androidai.FunctionManager;
import gxprod.androidai.Question;
import gxprod.androidai.Question.Response;
import gxprod.androidai.regex.MatchResult;
import gxprod.androidai.regex.NamedPattern;
import gxprod.androidai.support.Lookup;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;
import android.widget.Toast;
/**
 * Text messaging. I've got this one
 * @author Josh Maleszewski
 */
public class SMSFunction extends Function implements AnswerReciever{
	
	private static final String SENT = "SMS_SENT";
	private static final String DELIVERED = "SMS_DELIVERED";
	
	private NamedPattern[]  patterns = new NamedPattern[] {
			NamedPattern.compile("read (me )?th(at|e) (last )?text( message)?"),
			NamedPattern.compile("who (was|is|sent|said) that"),
			NamedPattern.compile("who (text|messag)ed me last"),
			NamedPattern.compile("(reply|(tell|ask) (him|her|them)) (.*)$"),
			NamedPattern.compile("tell (([a-z]+ ){1,2})that (.*)$")
	};
	
	public String ReplyName;
	public String ReplyNumber;
	public String messageOut;
	
	@Override
	public MatchResult isMatch(String statement) {
		return super.isMatch(statement, patterns, 0.83f);
	}

	@Override
	public boolean execute(MatchResult match, BubbleAdapter adapter) {

		String[] lastMessage;
		String name, write, say;
		
		switch(match.MatchIndex) {

			case 0:		// read last text message
				lastMessage = Lookup.getLastMessage(AIActivity.get());	// parts: 0) id   1) address   2) body   3) date received
				if(lastMessage == null) {
					adapter.output("I cant find any messages");
					ReplyNumber = null;
					return true;
				} else if(lastMessage.length == 0) {	
					adapter.output("I cant find any messages");
					ReplyNumber = null;
					return true;
				}
				ReplyNumber = lastMessage[1];
				name = Lookup.getNameFromNumber(AIActivity.get(), lastMessage[1]);
				if(name.contains(lastMessage[1]) | lastMessage[1].contains(name)) {
					write = "&lt;" + name + "&gt;<br/>" + lastMessage[2]; 
					ReplyName = "";	
				} else {
					write = "<b>" +name +"</b> &lt;" + lastMessage[1] + "&gt;<br/>" + lastMessage[2];
					ReplyName = name;
				}
				say = name + " said; " + lastMessage[2];  
				adapter.output(write, say);
				break;

				
			case 1:
			case 2:
				lastMessage = Lookup.getLastMessage(AIActivity.get());
				ReplyNumber = lastMessage[1];
				name = Lookup.getNameFromNumber(AIActivity.get(), lastMessage[1]);				
				
				if(name.contains(ReplyNumber) | ReplyNumber.contains(name)) {
					say = "I don't recognise the number, they said: " + lastMessage[2];
					write = "&lt;" + name + "&gt;<br/>" + lastMessage[2]; 
				} else {
					write = "<b>" +name +"</b> &lt;" + lastMessage[1] + "&gt;<br/>" + lastMessage[2];
					say = "It was " + name + ", who said: " + lastMessage[2];
				}					
				adapter.output(write, say);
				break;
				
				
			case 3:
				if(ReplyNumber == null) 
					adapter.output("I don't know who you are replying to");	
				else {
					messageOut = match.Matcher.group(4);
					send(adapter);					
				}

				break;

			case 4:
				messageOut = match.Matcher.group(3);
				ReplyName = match.Matcher.group(1);
				ReplyNumber = Lookup.lookupNumberFromName(AIActivity.get(), ReplyName);
				send(adapter);				
				break;

			default:
				return false;
		}		
		return true;
	}

	private void send(BubbleAdapter adapter) {
		if(FunctionManager.isVoice()) {
			StringBuilder sb = new StringBuilder();
			sb.append("<html>Send text to <b>");
			sb.append(ReplyName);
			sb.append("</b>:\n");
			sb.append(messageOut);
			sb.append("\"</html>");
			Question q = new Question(sb.toString(),this, "SMSReply");
			q.Response = q.new YesNoResponse(1);
			AIActivity.get().manager.askQuestion(q, "Is this correct?");
		} else {
			adapter.output("Sending...");
			sendSMS(ReplyNumber, messageOut, adapter);
		}
	}


	public void onAnswer(String answer, Question question, Response response, BubbleAdapter adapter) {
		if(question.Tag.equals("SMSReply")){
			int choice = ((Question.ChoiceResponse)response).Selected;
			if(choice == 0){				// yes
				adapter.output("Sending");
				AIActivity.get().manager.request = null;
				sendSMS(ReplyNumber, messageOut, adapter);
			} else if (choice == 1) {			// no, *
				messageOut = ((Question.ChoiceResponse)response).getMatch(answer).Matcher.group("msg");
			}
		}
	}



	@Override
	public boolean cullFunction(String statement) { return true; }


	/** 
	 * Sends a text massage to a given number.
	 */
	public static void sendSMS(final String phoneNumber, String message, final BubbleAdapter adapter) {        


		final Context context = AIActivity.get();

		PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, new Intent(SENT), 0);
		PendingIntent deliveredPI = PendingIntent.getBroadcast(context, 0, new Intent(DELIVERED), 0);
		
		context.registerReceiver(new BroadcastReceiver(){			//---when the SMS has been sent---
			@Override
			public void onReceive(Context arg0, Intent arg1) {
				switch (getResultCode()) {

					case Activity.RESULT_OK:
						adapter.postoutput("Message sent to <b>" + Lookup.getNameFromNumber(context, phoneNumber) + "</b>", "Message sent");
						break;

					case SmsManager.RESULT_ERROR_NO_SERVICE:
					case SmsManager.RESULT_ERROR_NULL_PDU:
					case SmsManager.RESULT_ERROR_RADIO_OFF:
					case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
					default:
						adapter.output("I was unable to send that message. Error Code: " + getResultCode());
						break;
				}
			}
		}, new IntentFilter(SENT));

		
		context.registerReceiver(new BroadcastReceiver(){			//---when the SMS has been delivered---
			@Override
			public void onReceive(Context arg0, Intent arg1) {
				switch (getResultCode()) {
					
					case Activity.RESULT_OK:
						Toast.makeText(context, "Message Sent", Toast.LENGTH_SHORT).show();
						break;
					case Activity.RESULT_CANCELED:
						Toast.makeText(context, "I was unable to send that message", Toast.LENGTH_LONG).show();
						break;                        
				}
			}
		}, new IntentFilter(DELIVERED));
		SmsManager sms = SmsManager.getDefault();
		sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);        
	}
}